package org.budo.shiro.session.dao.redis;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.eis.AbstractSessionDAO;
import org.budo.jdbc.dao.BudoJdbcDao;
import org.budo.support.slf4j.Slf4j;
import org.slf4j.Logger;

/**
 * 基类
 * 
 * @author lmw
 */
public abstract class AbstractBudoShiroRedisSessionDao extends AbstractSessionDAO {
    protected static final String KEYS_SQL = "SELECT key FROM session_keys WHERE key LIKE ?";

    protected static final String GET_SQL = "SELECT value FROM session_get WHERE key=?";

    protected static final String SET_SQL = "UPDATE set_session SET value=? WHERE key=?";

    protected static final String EXPIRE_SQL = "UPDATE expire_session SET expire=? WHERE key=?";

    protected static final String DEL_SQL = "DELETE FROM del_session WHERE key=?";

    private static final Logger log = Slf4j.getLogger();

    private BudoJdbcDao budoJdbcDao;

    private String sessionIdPrefix = "Budo:Session:Shiro:";

    public String getSessionIdPrefix() {
        return this.sessionIdPrefix;
    }

    public void setSessionIdPrefix(String sessionIdPrefix) {
        this.sessionIdPrefix = sessionIdPrefix;
    }

    public BudoJdbcDao getBudoJdbcDao() {
        return budoJdbcDao;
    }

    public void setBudoJdbcDao(BudoJdbcDao budoJdbcDao) {
        this.budoJdbcDao = budoJdbcDao;
    }

    /**
     * @return 可能返回空值
     */
    protected InputStream serialize(Session session) {
        if (null == session) {
            return null;
        }

        try {
            ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(out);
            objectOutputStream.writeObject(session);
            objectOutputStream.flush();
            return new ByteArrayInputStream(out.toByteArray());
        } catch (Throwable e) {
            log.error("#64 serialize error, session=" + session + ", e=" + e, e);
            return null;
        }
    }

    /**
     * @return 可能返回空值
     */
    protected Serializable deserialize(InputStream inputStream) {
        if (null == inputStream) {
            return null;
        }

        try {
            ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
            return (Serializable) objectInputStream.readObject();
        } catch (Throwable e) {
            log.error("#77 deserialize error, inputStream=" + inputStream + ", e=" + e, e);
            return null;
        }
    }
}